package com.aeye.mbr.upms.client.interceptor;

import com.aeye.mbr.common.util.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.regex.Pattern;

/**
 * <p>Description: </p>
 *
 * @author zhouchuanbo
 * @version 1.0
 * @date 2018/3/27 0027
 */
public class NewXssFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(NewXssFilter.class);

    FilterConfig filterConfig = null;

    private String failPage = "/error.jsp";// 发生注入时，跳转页面
    @Override
    public void destroy() {
        this.filterConfig = null;
    }

    @Override
    public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) sRequest;          
        HttpServletResponse response = (HttpServletResponse) sResponse;     
        String path = ((HttpServletRequest) request).getContextPath();
        String basePath = request.getScheme() + "://" + request.getServerName()
                + ":" + request.getServerPort() + path + "/";
        


        String csrf = request.getParameter("csrf");

        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        String ddd = request.getSession().getId().toString();
        String ff = session.getId().toString();
        String aaa = CSRFTokenManager.class.getName() + ".tokenval" + "_" + session.getId();

        String token =  RedisUtil.get(CSRFTokenManager.class
                .getName() + ".tokenval" + "_" + session.getId());


        // HTTP 头设置 Referer过滤
        String referer = request.getHeader("Referer"); // REFRESH
        if (referer != null && referer.indexOf(basePath) < 0) {
        	request.getRequestDispatcher(
                    request.getRequestURI()).forward(
                    request, response);
            if (request.getHeader("x-requested-with")!= null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){

                response.setHeader("SECURITYSTATUS", "NOT");
                response.setHeader("CONTEXTPATH", basePath+"sso/error.html");
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                return;
            }

            request.getRequestDispatcher("/sso/error.html").forward(request, response);
            log.error("=====星号星号=====:" + request.getRequestURI());
            log.error("=====http头请求referer为 =====:" + referer);
            return;
        }

        String uri = request.getRequestURI();

        String inj = xss(request);

        if (StringUtils.isNotEmpty(inj)) {
        	if (request.getHeader("x-requested-with")!= null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
        		
        		 response.setHeader("SECURITYSTATUS", "NOT");  
                 response.setHeader("CONTEXTPATH", basePath+"sso/error.html");  
                 response.setStatus(HttpServletResponse.SC_FORBIDDEN);  
                 return;  
        	}

            request.getRequestDispatcher("/sso/error.html").forward(request, response);
            log.error("=====星号星号=====:" + request.getRequestURI());
            log.error("=====字符=====:" + inj);
            return;

        } else {
            // 传递控制到下一个过滤器
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    public String xss(ServletRequest request) {
        Enumeration e = request.getParameterNames();
        String attributeName;
        String attributeValues[];
        String inj = "";
        while (e.hasMoreElements()) {
            attributeName = (String) e.nextElement();
            attributeValues = request.getParameterValues(attributeName);
            for (int i = 0; i < attributeValues.length; i++) {
                if (attributeValues[i] == null || attributeValues[i].equals(""))
                {
                    continue;
                }

                inj = stripXSS(attributeValues[i]);
                if (StringUtils.isNotEmpty(inj)) {
                    return attributeValues[i] + "包含特殊字符，去掉字符后为："+inj;
                }
            }
        }
        return inj;
    }

    private String stripXSS(String value)
    {
        String oldValue = value;
        if (StringUtils.isNotEmpty(value))
        {
            value = value.replaceAll("", "");
            // Avoid anything between script tags
            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a src='...' type of expression
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome </script> tag
            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid eval(...) expressions
            scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid expression(...) expressions
            scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid javascript:... expressions
            scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid vbscript:... expressions
            scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid onload= expressions
            scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");

            scriptPattern = Pattern.compile("<iframe>(.*?)</iframe>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");

            scriptPattern = Pattern.compile("</iframe>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<iframe(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            if (oldValue.equals(value))
            {
                return "";
            }
            if (StringUtils.isEmpty(value))
            {
            	return oldValue;
            }
            
        }else{
            return "";
        }
        return value;
    }

}